{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Machine Learning with K Nearest Neighbors\n",
    "\n",
    "In this micro-project, we'll use the KNN algorithm to classify instances from a fake dataset into one or the other target class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv('../data/KNN_Project_Data')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>XVPM</th>\n",
       "      <th>GWYH</th>\n",
       "      <th>TRAT</th>\n",
       "      <th>TLLZ</th>\n",
       "      <th>IGGA</th>\n",
       "      <th>HYKR</th>\n",
       "      <th>EDFS</th>\n",
       "      <th>GUUB</th>\n",
       "      <th>MGJM</th>\n",
       "      <th>JHZC</th>\n",
       "      <th>TARGET CLASS</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1636.670614</td>\n",
       "      <td>817.988525</td>\n",
       "      <td>2565.995189</td>\n",
       "      <td>358.347163</td>\n",
       "      <td>550.417491</td>\n",
       "      <td>1618.870897</td>\n",
       "      <td>2147.641254</td>\n",
       "      <td>330.727893</td>\n",
       "      <td>1494.878631</td>\n",
       "      <td>845.136088</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1013.402760</td>\n",
       "      <td>577.587332</td>\n",
       "      <td>2644.141273</td>\n",
       "      <td>280.428203</td>\n",
       "      <td>1161.873391</td>\n",
       "      <td>2084.107872</td>\n",
       "      <td>853.404981</td>\n",
       "      <td>447.157619</td>\n",
       "      <td>1193.032521</td>\n",
       "      <td>861.081809</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1300.035501</td>\n",
       "      <td>820.518697</td>\n",
       "      <td>2025.854469</td>\n",
       "      <td>525.562292</td>\n",
       "      <td>922.206261</td>\n",
       "      <td>2552.355407</td>\n",
       "      <td>818.676686</td>\n",
       "      <td>845.491492</td>\n",
       "      <td>1968.367513</td>\n",
       "      <td>1647.186291</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1059.347542</td>\n",
       "      <td>1066.866418</td>\n",
       "      <td>612.000041</td>\n",
       "      <td>480.827789</td>\n",
       "      <td>419.467495</td>\n",
       "      <td>685.666983</td>\n",
       "      <td>852.867810</td>\n",
       "      <td>341.664784</td>\n",
       "      <td>1154.391368</td>\n",
       "      <td>1450.935357</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1018.340526</td>\n",
       "      <td>1313.679056</td>\n",
       "      <td>950.622661</td>\n",
       "      <td>724.742174</td>\n",
       "      <td>843.065903</td>\n",
       "      <td>1370.554164</td>\n",
       "      <td>905.469453</td>\n",
       "      <td>658.118202</td>\n",
       "      <td>539.459350</td>\n",
       "      <td>1899.850792</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          XVPM         GWYH         TRAT        TLLZ         IGGA  \\\n",
       "0  1636.670614   817.988525  2565.995189  358.347163   550.417491   \n",
       "1  1013.402760   577.587332  2644.141273  280.428203  1161.873391   \n",
       "2  1300.035501   820.518697  2025.854469  525.562292   922.206261   \n",
       "3  1059.347542  1066.866418   612.000041  480.827789   419.467495   \n",
       "4  1018.340526  1313.679056   950.622661  724.742174   843.065903   \n",
       "\n",
       "          HYKR         EDFS        GUUB         MGJM         JHZC  \\\n",
       "0  1618.870897  2147.641254  330.727893  1494.878631   845.136088   \n",
       "1  2084.107872   853.404981  447.157619  1193.032521   861.081809   \n",
       "2  2552.355407   818.676686  845.491492  1968.367513  1647.186291   \n",
       "3   685.666983   852.867810  341.664784  1154.391368  1450.935357   \n",
       "4  1370.554164   905.469453  658.118202   539.459350  1899.850792   \n",
       "\n",
       "   TARGET CLASS  \n",
       "0             0  \n",
       "1             1  \n",
       "2             1  \n",
       "3             0  \n",
       "4             0  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Standardizing the Variables\n",
    "\n",
    "Because of the type of data we're dealing with, it's important to standardize the variables before training our model. Skewed distribution of variables makes it harder for our model to deal with it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaler = StandardScaler()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['XVPM', 'GWYH', 'TRAT', 'TLLZ', 'IGGA', 'HYKR', 'EDFS', 'GUUB', 'MGJM',\n",
       "       'JHZC', 'TARGET CLASS'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course, we don't need to scale the target class, so we'll ignore that during scaler fitting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StandardScaler()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scaler.fit(df.drop('TARGET CLASS',axis=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we'll use the .transform() method to transform the features to a scaled version."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaled_feats = scaler.transform(df.drop('TARGET CLASS',axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Converting the scaled features to a dataframe\n",
    "scaled_df = pd.DataFrame(scaled_feats)\n",
    "scaled_df.columns =['XVPM', 'GWYH', 'TRAT', 'TLLZ', 'IGGA', 'HYKR', 'EDFS', 'GUUB', 'MGJM',\n",
    "       'JHZC']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>XVPM</th>\n",
       "      <th>GWYH</th>\n",
       "      <th>TRAT</th>\n",
       "      <th>TLLZ</th>\n",
       "      <th>IGGA</th>\n",
       "      <th>HYKR</th>\n",
       "      <th>EDFS</th>\n",
       "      <th>GUUB</th>\n",
       "      <th>MGJM</th>\n",
       "      <th>JHZC</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.568522</td>\n",
       "      <td>-0.443435</td>\n",
       "      <td>1.619808</td>\n",
       "      <td>-0.958255</td>\n",
       "      <td>-1.128481</td>\n",
       "      <td>0.138336</td>\n",
       "      <td>0.980493</td>\n",
       "      <td>-0.932794</td>\n",
       "      <td>1.008313</td>\n",
       "      <td>-1.069627</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.112376</td>\n",
       "      <td>-1.056574</td>\n",
       "      <td>1.741918</td>\n",
       "      <td>-1.504220</td>\n",
       "      <td>0.640009</td>\n",
       "      <td>1.081552</td>\n",
       "      <td>-1.182663</td>\n",
       "      <td>-0.461864</td>\n",
       "      <td>0.258321</td>\n",
       "      <td>-1.041546</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.660647</td>\n",
       "      <td>-0.436981</td>\n",
       "      <td>0.775793</td>\n",
       "      <td>0.213394</td>\n",
       "      <td>-0.053171</td>\n",
       "      <td>2.030872</td>\n",
       "      <td>-1.240707</td>\n",
       "      <td>1.149298</td>\n",
       "      <td>2.184784</td>\n",
       "      <td>0.342811</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.011533</td>\n",
       "      <td>0.191324</td>\n",
       "      <td>-1.433473</td>\n",
       "      <td>-0.100053</td>\n",
       "      <td>-1.507223</td>\n",
       "      <td>-1.753632</td>\n",
       "      <td>-1.183561</td>\n",
       "      <td>-0.888557</td>\n",
       "      <td>0.162310</td>\n",
       "      <td>-0.002793</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-0.099059</td>\n",
       "      <td>0.820815</td>\n",
       "      <td>-0.904346</td>\n",
       "      <td>1.609015</td>\n",
       "      <td>-0.282065</td>\n",
       "      <td>-0.365099</td>\n",
       "      <td>-1.095644</td>\n",
       "      <td>0.391419</td>\n",
       "      <td>-1.365603</td>\n",
       "      <td>0.787762</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       XVPM      GWYH      TRAT      TLLZ      IGGA      HYKR      EDFS  \\\n",
       "0  1.568522 -0.443435  1.619808 -0.958255 -1.128481  0.138336  0.980493   \n",
       "1 -0.112376 -1.056574  1.741918 -1.504220  0.640009  1.081552 -1.182663   \n",
       "2  0.660647 -0.436981  0.775793  0.213394 -0.053171  2.030872 -1.240707   \n",
       "3  0.011533  0.191324 -1.433473 -0.100053 -1.507223 -1.753632 -1.183561   \n",
       "4 -0.099059  0.820815 -0.904346  1.609015 -0.282065 -0.365099 -1.095644   \n",
       "\n",
       "       GUUB      MGJM      JHZC  \n",
       "0 -0.932794  1.008313 -1.069627  \n",
       "1 -0.461864  0.258321 -1.041546  \n",
       "2  1.149298  2.184784  0.342811  \n",
       "3 -0.888557  0.162310 -0.002793  \n",
       "4  0.391419 -1.365603  0.787762  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scaled_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Model Building"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Begin with splitting the data into training and test sets\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = scaled_df\n",
    "y = df['TARGET CLASS']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=101)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fitting our model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn = KNeighborsClassifier(n_neighbors=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(n_neighbors=1)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Predictions and Evaluations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "predictions = knn.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import classification_report,confusion_matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[109  43]\n",
      " [ 41 107]]\n"
     ]
    }
   ],
   "source": [
    "print(confusion_matrix(y_test,predictions))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.73      0.72      0.72       152\n",
      "           1       0.71      0.72      0.72       148\n",
      "\n",
      "    accuracy                           0.72       300\n",
      "   macro avg       0.72      0.72      0.72       300\n",
      "weighted avg       0.72      0.72      0.72       300\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(classification_report(y_test,predictions))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Choosing a K Value\n",
    "\n",
    "A major part of building a ML model with KNN, is choosing a K value to improve the performance of our model. Let's go ahead and use the elbow method to do that.\n",
    "\n",
    "We will create a loop that trains various KNN models with different k values, then keep track of the error_rate for each of these models with a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "error_rate =[]\n",
    "for i in range(1,50):\n",
    "    knn = KNeighborsClassifier(n_neighbors=i)\n",
    "    knn.fit(X_train,y_train)\n",
    "    predictions = knn.predict(X_test)\n",
    "    error_rate.append(np.mean(predictions != y_test))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, to make it easier to see what values of K had lower error rates, we'll create a plot using the information from our for loop."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Error Rate')"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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RyEiIiLZTpc1M+iKK+Dee6OOQkRERLKZkrMMuuUW+Mtfoo5CREREspmSswyqqFCdMxEREUlOyVkGVVRotKaIiIgkp+Qsg5SciYiISGeUnGVQZSXU1UUdhYiIiGQzldLIoJtuCkpqiIiIiHREyVkGddPeFhERkU7osmYGPfkknHkmfPhh1JGIiIhItlJylkFvvgm33gpr10YdiYiIiGQrJWcZpIefi4iISGeUnGWQkjMRERHpjJKzDFJyJiIiIp1RcpZBlZWw006weXPUkYiIiEi2UnGHDBo0SGfNREREJDmdORMRERHJIkrOMmzcOJg1K+ooREREJFspOcuwxx6DxYujjkJERESylZKzDKuogPXro45CREREspWSswyrqNCgABEREemYkrMMU3ImIiIiySg5y7A99oB+/aKOQkRERLKV6pxl2C9/GXUEIiIiks105kxEREQkiyg5y7C//AW++EX473+jjkRERESyUajJmZkdbWavmdlyM5uaYPmFZvaKmS0zs0fNbEib5eVmtsrMrgszzkz64AN48kklZyIiIpJYaMmZmRUDs4BRwHBgjJkNb9PsOaDa3UcA84DpbZb/FHgyrBijUFER/NSITREREUkkzDNnBwPL3X2Fu28G7ga+2rqBuz/u7hvjk0uAgS3LzOxAYADwtxBjzDglZyIiIpJMmMnZ7sDbraZXxed15CxgAYCZFQFXA98PLbqIVFYGP5WciYiISCJZUUrDzE4BqoEvxmdNAB5y91Vmluxz44BxAIMHDw47zLTYeWc44AAoK4s6EhEREclGYSZn7wCDWk0PjM/bhpkdCVwKfNHdY/HZI4EvmNkEoDfQ3czq3H2bQQXufhNwE0B1dbWnvwvpN2AAPPts1FGIiIhItgozOXsa2MvM9iRIyk4GxrZuYGYHADcCR7v76pb57v7tVm3OIBg00G60p4iIiEi+Ce2eM3ffAkwCHgZeBe5195fN7HIzGx1vNoPgzNh9Zva8mc0PK55scvTRcNllUUchIiIi2SjUe87c/SHgoTbzftTq/ZEprONW4NZ0xxalFSu2DgwQERERaU1PCIhARYVGa4qIiEhiSs4ioORMREREOqLkLAKVlbB+fdRRiIiISDbKijpnhebAA6GkJOooREREJBspOYvAxRdHHYGIiIhkq04va1rgFDP7UXx6sJkdHH5oIiIiIoUnlXvO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\n",
      "text/plain": [
       "<Figure size 720x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "plt.plot(range(1,50),error_rate,color='blue', linestyle='dashed', marker='o',\n",
    "         markerfacecolor='red', markersize=10)\n",
    "plt.title('Error Rate vs. K Value')\n",
    "plt.xlabel('K')\n",
    "plt.ylabel('Error Rate')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Looking at the plot,31 seems to be reasonable value for K. So let's retrain the model using that."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Retrain with new K Value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn = KNeighborsClassifier(n_neighbors=31)\n",
    "knn.fit(X_train,y_train)\n",
    "predictions = knn.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[123  29]\n",
      " [ 19 129]]\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.87      0.81      0.84       152\n",
      "           1       0.82      0.87      0.84       148\n",
      "\n",
      "    accuracy                           0.84       300\n",
      "   macro avg       0.84      0.84      0.84       300\n",
      "weighted avg       0.84      0.84      0.84       300\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(confusion_matrix(y_test,predictions))\n",
    "print(classification_report(y_test,predictions))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And voila! Our model performs better! \n",
    "\n",
    "This concludes this micro-project."
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
